﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Devices;
using System.Threading;

namespace AllenalaMente.Games.Quake
{
    public partial class Quake : UserControl, GameInterface
    {
        private int score = 0, giuste = 0, sbagliate = 0;
        private DispatcherTimer updateTimer, startTimer;
        private TimeSpan startTime;
        private UITimer UIgameTimer;
        private UIScore UIgameScore;
        private List<Rock> rockList;
        private int winsCounter = 0, difficulty = 0;
        private int[] ranges;
        //int partialscore = 0;

        public Quake()
        {
            InitializeComponent();

            //creo una lista di rocks
            rockList = new List<Rock>();

            ranges = new int[] { 3, 4, 5, 6, 7};

            //set_rocks();

            // Start timer
            startTimer = new DispatcherTimer();
            startTimer.Interval = TimeSpan.FromMilliseconds(600);
            startTimer.Tick += new EventHandler(startTimer_Tick);
            startTimer.Start();
            startTime = TimeSpan.FromSeconds(3);
            TextBlockReady.Text = Locale.Strings.Ready;

            // Update timer
            updateTimer = new DispatcherTimer();
            updateTimer.Interval = TimeSpan.FromMilliseconds(20);
            updateTimer.Tick += new EventHandler(updateTimer_Tick);
            //updateTimer.Start();

            // UI Game timer
            UIgameTimer = new UITimer(60);
            LayoutRoot.Children.Add(UIgameTimer);
            UIgameTimer.timeOut += new EventHandler(game_TimeOut);
            //UIgameTimer.Start();

            // UI Game Score
            UIgameScore = new UIScore();
            LayoutRoot.Children.Add(UIgameScore);
            Canvas.SetLeft(UIgameScore, 750);

        }

        private void set_rocks()
        {
            // resetta la precendete lista di rocks
            rockList.Clear();
            //svuoto il canvas di asteroids
            asteroidsCanvas.Children.Clear();

            Random rnd = new Random();

            for (int i = 0; i < rnd.Next(ranges[difficulty], ranges[difficulty] + 2); i++)
            {
                Rock r = new Rock();
                rockList.Add(r);
                rockList[i].velocity = rnd.Next(6, 7);
                rockList[i].height = rnd.Next(20,50);
                rockList[i].Width = 10;
                asteroidsCanvas.Children.Add(r);
                Canvas.SetTop(r, -100 - rockList[i].height);
                Canvas.SetLeft(r, rnd.Next(50, 750));
                r.MouseLeftButtonDown += new MouseButtonEventHandler(r_MouseLeftButtonDown);
                r.Opacity = 0;
            }

            //activeVib = false;
        }

        void r_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ((Rock)sender).rock_exp.Visibility = Visibility.Visible;
            ((Rock)sender).rock_exp.Width = ((Rock)sender).rock.Width;
            ((Rock)sender).rock_exp.Height = ((Rock)sender).rock.Height;
            ((Rock)sender).IsHitTestVisible = false;
            ((Rock)sender).rockPopped += new EventHandler(rock_Popped);
            ((Rock)sender).popFade();
        }

        public event GameEvent GameEnd;

        float timer = 5, pointsTimer = 2; bool activeVib = false, wins = true, drawPoint = false, sconfitta = false; Random rnd = new Random();
        private void updateTimer_Tick(object sender, EventArgs e)
        {
            timer -= 0.1f;

            if (timer < 0)
            {
                if (!activeVib)
                {
                    VibrateController.Default.Start(TimeSpan.FromSeconds(0.2));
                    activeVib = true;
                }

                for (int i = 0; i < rockList.Count; i++)
                {
                    var y = Canvas.GetTop(rockList[i]);
                    Canvas.SetTop(rockList[i], y + rockList[i].velocity);

                    if (y > -20)
                        rockList[i].Opacity = 1;

                    // sconfitta
                    if ((y + rockList[i].velocity >= 400) && (!rockList[i].destroied))
                    {
                        if (!sconfitta)
                        {
                            // Prevent disaster
                            score -= 50;
                            if(score < 0)
                                score = 0;

                            UIgameScore.SetScore(score);
                            bg_image_exp.Visibility = Visibility.Visible;
                            activeVib = false;
                            explosionAfterTap();
                            sbagliate += 1;
                            wins = false;
                            sconfitta = true;
                            drawPoint = true;
                        }


                    }


                }

                // controllo che ho distrutto tutto, vittoria
                if (rockList.Count <= 0)
                {
                    // prima che inizi la prossima serie
                    // ogni 3 vittorie aumenta difficoltà
                    if (winsCounter == 3)
                    {
                        winsCounter = 0;
                        if (difficulty < 4)
                            difficulty++;
                    }
                    winsCounter++;

                    score += ((difficulty * 10) + 100);
                    UIgameScore.SetScore(score);
                    timer = 4;
                    activeVib = false;
                    drawPoint = true;
                    wins = true;
                    set_rocks();
                    giuste += 1;
                }

            }

            if (drawPoint)
            {
                drawPoints((difficulty * 10) + 100, wins);
            }

        }

        private void drawPoints(int point, bool wins)
        {
            points.Visibility = Visibility.Visible;
            if (!wins)
            {
                points.Foreground = new SolidColorBrush(Colors.Red);
                points.Text = " -" + 30;
            }
            else
            {
                points.Foreground = new SolidColorBrush(Colors.Black);
                points.Text = "+" + point.ToString();
            }

           
            Canvas.SetTop(points, Canvas.GetTop(points) - 5);
            pointsTimer -= 0.1f;

            if (pointsTimer <= 0)
            {
                drawPoint = false;
                points.Visibility = Visibility.Collapsed;
                pointsTimer = 2;
                Canvas.SetTop(points, 160);
            }

        }

        private void explosionAfterTap()
        {
            Storyboard pointsAnimation = new Storyboard();
            //if((int)updateTimer.Tick() < 2)
            pointsAnimation.Duration = TimeSpan.FromSeconds(1);

            //textValue.Text = "+5";
            //textValue.FontSize = 32;
            //textValue.Foreground = new SolidColorBrush(Colors.Green);
            //textRotation.Angle = 0;
            DoubleAnimation explosion = new DoubleAnimation();
            explosion.Duration = pointsAnimation.Duration;
            //explosion.From = Canvas.GetTop(textValue);
            //explosion.To = explosion.From - 50;
            pointsAnimation.Children.Add(explosion);
            Storyboard.SetTarget(explosion, bg_image_exp);
            Storyboard.SetTargetProperty(explosion, new PropertyPath("(Canvas.Top)"));

            //DoubleAnimation textBlockOpacity = new DoubleAnimation();
            //textBlockOpacity.Duration = pointsAnimation.Duration;
            //textBlockOpacity.From = 1;
            //textBlockOpacity.To = 0;
            //pointsAnimation.Children.Add(textBlockOpacity);
            //Storyboard.SetTarget(textBlockOpacity, textValue);
            //Storyboard.SetTargetProperty(textBlockOpacity, new PropertyPath("(UIElement.Opacity)"));
            pointsAnimation.Begin();

            pointsAnimation.Completed += new EventHandler(explosionAnimation_Completed);
        }

        // sconfitta
        void explosionAnimation_Completed(object sender, EventArgs e)
        {
            bg_image_exp.Visibility = Visibility.Collapsed;
            timer = 4;
            sconfitta = false;
            set_rocks();

        }

        void rock_Popped(object sender, EventArgs e)
        {
            LayoutRoot.Children.Remove(((Rock)sender));
            rockList.Remove(((Rock)sender));
        }

        private void startTimer_Tick(object sender, EventArgs e)
        {
            startTime = startTime.Subtract(TimeSpan.FromSeconds(1));
            if (startTime.Seconds < 2)
                TextBlockReady.Text = Locale.Strings.GO;
            if (startTime.Seconds < 1)
            {
                // The countdown is finished, the game can start
                startTimer.Tick -= startTimer_Tick;
                CanvasCountdown.Visibility = Visibility.Collapsed;
                updateTimer.Start();
                UIgameTimer.Start();

                set_rocks();
            }
        }

        private void game_TimeOut(object sender, EventArgs e)
        {
            // Finito il tempo

            VibrateController.Default.Stop();
            updateTimer.Stop();
            GameEventArgs gea = new GameEventArgs();
            gea.reason = GameCloseReason.Timeout;
            gea.score = this.score;
            gea.giuste = this.giuste;
            gea.sbagliate = this.sbagliate;
            if (GameEnd != null)
                GameEnd(this, gea);
        }
    }
}
